package com.gp.gback.system.common.mapping_support;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * Created by honghua.dong1 on 16/11/17.
 */
public class JsonUtil {

    private static ObjectMapper objectMapper = new ObjectMapper();

    public static Map<String, String[]> jsonToMap(InputStream inputStream) {

        try {
            Object obj = objectMapper.readValue(inputStream, Object.class);
            Map result = transfer("", new HashMap<String, List<String>>(), obj);
            Iterator<Map.Entry> iterator = result.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = iterator.next();
                String key = (String) entry.getKey();
                Object value = entry.getValue();
                if (value instanceof List) {
                    List<String> values = (List<String>) value;
                    result.put(key, values.toArray(new String[]{}));
                }
            }
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Collections.emptyMap();
    }

    public static Map<String, String[]> jsonToMap(String input) {
        return jsonToMap(new ByteArrayInputStream(input.getBytes()));
    }

    private static Map transfer(String prefix, Map<String, List<String>> result, Object jsonObject) {
        if (jsonObject instanceof Map) {
            Iterator<Map.Entry> it = ((Map) jsonObject).entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry entry = it.next();
                String key = (String) entry.getKey();
                Object value = entry.getValue();
                String fullKey = prefix + "." + key;
                if (value instanceof String) {
                    fullKey = fullKey.substring(1);
                    putIntoMap(result, fullKey, value.toString());
                } else {
                    transfer(fullKey, result, value);
                }
            }
        } else if (jsonObject instanceof List) {
            for (Object obj : (List) jsonObject) {
                if (obj instanceof String) {
                    putIntoMap(result, prefix.substring(1), obj.toString());
                } else {
                    transfer(prefix, result, obj);
                }
            }
        }
        return result;
    }

    private static void putIntoMap(Map<String, List<String>> mapContainer, String key, String value) {
        List<String> valueList = null;
        if (mapContainer.containsKey(key)) {
            valueList = mapContainer.get(key);
        } else {
            valueList = new ArrayList<String>();
        }
        valueList.add(value);
        mapContainer.put(key, valueList);
    }
}